package com.ndp.fb.mq.service.schedulerservice.thirdpictureaudit;

import com.alibaba.dubbo.config.annotation.Reference;
import com.ndp.fb.config.ConfigCentre;
import com.ndp.fb.constant.ConfigConst;
import com.ndp.fb.enums.adcampaigngroups.AdCampaignGroupStatus;
import com.ndp.fb.enums.adresource.ThirdPicReviewStatus;
import com.ndp.fb.enums.adsetstatus.AdSetStatus;
import com.ndp.fb.enums.publish.AdObjective;
import com.ndp.fb.enums.publish.OptimizationGoal;
import com.ndp.fb.fbagent.service.AdCampaignGroupFBService;
import com.ndp.fb.fbagent.service.AdCreativeFBService;
import com.ndp.fb.fbagent.service.AdSetFBService;
import com.ndp.fb.fbagent.service.OauthFbService;
import com.ndp.fb.model.AdResourceStats;
import com.ndp.fb.model.fbagent.param.APIPriority;
import com.ndp.fb.model.fbagent.param.ApiCallBackTarget;
import com.ndp.fb.model.fbagent.param.IdParam;
import com.ndp.fb.model.fbagent.param.adcampaigngroups.AdCampaignParam;
import com.ndp.fb.model.fbagent.param.adcreative.*;
import com.ndp.fb.model.fbagent.param.adset.AdSetParam;
import com.ndp.fb.model.fbagent.result.common.FBSingleId;
import com.ndp.fb.mongo.api.AdResourceStatsMongoService;
import com.ndp.fb.mq.api.service.schedulerservice.AdAccountsSchedulerService;
import com.ndp.fb.rdb.api.AdCampaignRdbService;
import com.ndp.fb.util.DateUtil;
import com.ndp.fb.util.ListUtil;
import com.ndp.fb.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 自动审核第三方提供的素材
 * Created by hermen.he on 2015/10/19.
 */
@Component
public class AutoCheckRecourceOneStep {
    private static Logger logger = LoggerFactory.getLogger(AutoCheckRecourceOneStep.class);
    private static final String CAMPAIGNS_REACHED_MAXIMUM = "Maximum number of campaigns reached";

    @Reference
    AdResourceStatsMongoService adResourceStatsMongoService;
    /**
     * 给fb放嗯的地址
     */
    private String NFS_CONFIG_FB_VISIT_DOMAIN = ConfigCentre.getString(ConfigConst.NFS_CONFIG_FB_VISIT_DOMAIN);
    private String NFS_CONFIG_DOMAIN = ConfigCentre.getString(ConfigConst.NFS_CONFIG_DOMAIN);
    @Autowired
    private AdAccountsSchedulerService adaccountsSchedulerService;
    @Reference
    private AdSetFBService adSetFBService;
    @Reference
    private AdCampaignGroupFBService adCampaignGroupFBService;

    @Reference
    private AdCampaignRdbService adCampaignGroupRdbService;

    @Reference
    private OauthFbService oauthFbService;

    @Reference
    private AdCreativeFBService adCreativeFBService;
    @Autowired
    private AutoCheckResourceFourStep autoCheckResourceFourStep;

    public void autoPublishAdCampaign() {
        logger.info("自动发营销活动autoPublishAdCampaign----begin");
        Long accountId = AutoCheckConstant.getFbAccountId();
        String accessToken = adaccountsSchedulerService.getAdaccountsToken(accountId);
        if (StringUtil.isEmpty(accessToken))
            return;
		long count = adResourceStatsMongoService.countUnReviewedImagesUploadByOutUi();
        if(count > 0)
        {
            AdCampaignParam campaignGroupParam = new AdCampaignParam();
            campaignGroupParam.setName("yeahmobi_中国NDP七区广告_campaign_evan");
            campaignGroupParam.setStatus(AdCampaignGroupStatus.ACTIVE.getStatus());
            campaignGroupParam.setApiPriorityCode(APIPriority.CreateAdCampaignGroups.getCode());
            campaignGroupParam.setApiCallbackTargetType(ApiCallBackTarget.AdPublish.AutoAdCampaign.getTargetType());
            campaignGroupParam.setObjective(AdObjective.MOBILE_APP_INSTALLS.getType());
            campaignGroupParam.setCallBack(true);
            campaignGroupParam.setFbAccountId(accountId);
            campaignGroupParam.setAccessToken(accessToken);
            campaignGroupParam.setResultClass(FBSingleId.class);

            adCampaignGroupFBService.createCampaignGroup(campaignGroupParam);
        }
    }

    public void autoPublishAdCampaignCallBack(Map<String, String> equipment, Object fbSingleId) {
        logger.info("自动发营销活动回来autoPublishAdCampaign----callback");
        if (fbSingleId instanceof FBSingleId) {
            autoPublishAdSet(((FBSingleId) fbSingleId).getId());
        } else if (fbSingleId.toString().indexOf(CAMPAIGNS_REACHED_MAXIMUM) > -1) {
            logger.error("自动发营销活动失败：：" + fbSingleId.toString());
            //到达最多去fb删掉账号下的营销活动
            Long accountId = AutoCheckConstant.getFbAccountId();
            String accessToken = adaccountsSchedulerService.getAdaccountsToken(accountId);
            List<Long> ids = adCampaignGroupRdbService.findByFbAccountIdToPause(accountId);
            IdParam param = new IdParam();
            param.setFbAccountId(accountId);
            param.setAccessToken(accessToken);
            for(Long id : ids) {
                param.setId(id);
                oauthFbService.deleteObject(param);
            }
        } else {
            logger.error("自动发营销活动失败：：" + fbSingleId.toString());
        }
    }

    public void autoPublishAdSet(Long adCampaignGroupId) {
        logger.info("自动发广告系列autoPublishAdSet----begin");
        Long accountId = AutoCheckConstant.getFbAccountId();
        String accessToken = adaccountsSchedulerService.getAdaccountsToken(accountId);
        if (StringUtil.isEmpty(accessToken))
            return;
        adSetFBService.createAdSet(generateAdSetFbParam(adCampaignGroupId, accountId, accessToken));
    }

    public void autoPublishAdSetCallBack(Map<String, String> equipment, Object fbSingleId) {
        logger.info("自动发广告系列autoPublishAdSet----callback");
        if (fbSingleId instanceof FBSingleId) {
            String adCampaignGroupId = equipment.get("adCampaignGroupId");
            autoPublishAdCreative(adCampaignGroupId, ((FBSingleId) fbSingleId).getId());
        } else {
            logger.error("自动发广告系列失败：：" + fbSingleId.toString());
        }
    }

    public void autoPublishAdCreative(String adCampaignGroupId, Long adSetId) {
        logger.info("自动发创意autoPublishAdCreative----begin");
        Long accountId = AutoCheckConstant.getFbAccountId();
        String accessToken = adaccountsSchedulerService.getAdaccountsToken(accountId);
        if (StringUtil.isEmpty(accessToken))
            return;
        //从mongo查询需要机器审核的图片
        Integer everyTimeAudit = ConfigCentre.getInteger(ConfigConst.THIRDPIC_EVERYTIME_AUDIT, 20);
        List<AdResourceStats> adResourceStatsList = adResourceStatsMongoService.findUnReviewedImagesUploadByOutUi(everyTimeAudit, new String[]{"mongodbId", "height", "name", "orgId", "visitPath", "width", "machineCnt"});
        if (ListUtil.isNotEmpty(adResourceStatsList)) {
            ObjectStorySpec objectStorySpec = new ObjectStorySpec();
            objectStorySpec.setPageId(AutoCheckConstant.getPageId());
            LinkData linkData;
            //构造CallToAction
            CallToActionValue callToActionValue = new CallToActionValue();
            callToActionValue.setLink(AutoCheckConstant.getApplicationUrl());
            callToActionValue.setLinkTitle("Bo");
            CallToAction callToAction = new CallToAction();
            callToAction.setType("INSTALL_MOBILE_APP");
            callToAction.setValue(callToActionValue);
            List<String> mongoIdList = new ArrayList<>();
            for (AdResourceStats adResourceStats : adResourceStatsList) {
                if ((adResourceStats.getHeight() != null && adResourceStats.getWidth() != null
                        && adResourceStats.getHeight().equals(628) && adResourceStats.getWidth().equals(1200))
                        || (adResourceStats.getHeight() != null && adResourceStats.getWidth() != null
                        && adResourceStats.getHeight().equals(600) && adResourceStats.getWidth().equals(600))) {
                    mongoIdList.add(adResourceStats.getMongodbId());
                    linkData = new LinkData();
                    linkData.setPictureName(adResourceStats.getName());
                    linkData.setPicture(getFBVisitPath(adResourceStats.getVisitPath()));
                    linkData.setLink(AutoCheckConstant.getApplicationUrl());
                    linkData.setMessage(adResourceStats.getName());
                    linkData.setCallToAction(callToAction);
                    objectStorySpec.setLinkData(linkData);
                    //构造创意参数
                    AdCreativeParam param = new AdCreativeParam();
                    param.setAccessToken(accessToken);
                    param.setFbAccountId(accountId);
                    param.setApiPriorityCode(APIPriority.CreateAdCreative.getCode());
                    param.setApiCallbackTargetType(ApiCallBackTarget.AdPublish.AutoAdCreative.getTargetType());
                    param.setObjectStorySpec(objectStorySpec);
                    param.setResultClass(FBSingleId.class);
                    param.setCallBack(true);
                    //需要回调传递的参数
                    Map<String, String> equip = new HashMap<>();
                    equip.put("adCampaignGroupId", adCampaignGroupId);
                    equip.put("adSetId", adSetId + "");
                    equip.put("mongdbId", adResourceStats.getMongodbId());
                    equip.put("orgId", adResourceStats.getOrgId() + "");
                    equip.put("machineCnt", (adResourceStats.getMachineCnt() == null || adResourceStats.getMachineCnt() == 0) ? "0" : adResourceStats.getMachineCnt() + "");
                    param.setEquipment(equip);
                    adCreativeFBService.createAdCreative(param);
                } else {
                    //图片尺寸不是1200*628 机器审核不通过
                    adResourceStatsMongoService.updateReviewStatus(adResourceStats.getMongodbId(), ThirdPicReviewStatus.MACHINE_REVIEW_NOPASS.getCode(), "素材尺寸必须为1200*628或者600*600", null);
                }

            }
            adResourceStatsMongoService.batchUpdateReviewStatus(mongoIdList, ThirdPicReviewStatus.MACHINE_REVIEWING.getCode());
        }
    }

    public void autoPublishAdCreativeCallBack(Map<String, String> equipment, Object fbSingleId) {
        logger.info("自动发创意autoPublishAdCreative----callback");
        if (equipment != null && StringUtil.isNotEmpty(equipment.get("adCampaignGroupId")) && StringUtil.isNotEmpty(equipment.get("adSetId"))) {
            Long adCampaignGroupId = Long.parseLong(equipment.get("adCampaignGroupId"));
            Long adSetId = Long.parseLong(equipment.get("adSetId"));
            String mongdbId = equipment.get("mongdbId");
            String orgId = equipment.get("orgId");
            int machineCnt = Integer.parseInt(equipment.get("machineCnt"));
            /**
             * 该图片发创意三次还是失败 则该图置为审核失败
             */
            if (fbSingleId instanceof FBSingleId) {
                autoCheckResourceFourStep.autoPublishAd(adCampaignGroupId, adSetId, ((FBSingleId) fbSingleId).getId(), mongdbId, orgId);
            } else if (machineCnt >= 6) {
                String exception = fbSingleId.toString();
                logger.error("自动发创意失败：：" + exception);
                adResourceStatsMongoService.updateReviewStatus(mongdbId, ThirdPicReviewStatus.MACHINE_REVIEW_NOPASS.getCode(), exception, null);
            } else {
                String exception = fbSingleId.toString();
                logger.error("自动发创意失败：：" + exception);
                adResourceStatsMongoService.updateReviewStatus(mongdbId, ThirdPicReviewStatus.WAIT_MACHINE_REVIEW.getCode(), exception, ++machineCnt);
            }
        }
    }

    /**
     * 重试adset参数
     */
    private AdSetParam generateAdSetFbParam(Long adCampaignGroupId, Long accountId, String accesstoken) {
        AdSetParam param = new AdSetParam();
        param.setAccessToken(accesstoken);
        param.setFbAccountId(accountId);
        param.setName("yeahmobi_中国NDP七区_adset_evan");
        param.setStatus(AdSetStatus.ACTIVE.getStatus());
        param.setDailyBudget(500);
        param.setStartTime(DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss") + "+08:00");              //2015-10-21 16:48:22+08:00
        param.setCampaignId(adCampaignGroupId);
        param.setTargeting("{\"age_max\":50,\"age_min\":13,\"behaviors\":[],\"excluded_geo_locations\":{},\"genders\":[2],\"geo_locations\":{\"countries\":[\"CN\"],\"location_types\":[\"recent\",\"home\"]},\"interests\":[],\"page_types\":[\"mobilefeed\",\"mobileexternal\"],\"user_device\":[\"iPad\",\"iPhone\"],\"user_os\":[\"iOS_ver_2.0_and_above\"]}");
        param.setPromotedObject("{'application_id' : " + AutoCheckConstant.getApplication() + ", 'object_store_url' : '" + AutoCheckConstant.getApplicationUrl() + "'}");
        param.setApiPriorityCode(APIPriority.CreateAdSet.getCode());
        param.setApiCallbackTargetType(ApiCallBackTarget.AdPublish.AutoAdSet.getTargetType());
        param.setResultClass(FBSingleId.class);
        param.setCallBack(true);
        //v2.4
        param.setOptimizationGoal(OptimizationGoal.LINK_CLICKS.getCode());
        param.setBillingEvent(OptimizationGoal.LINK_CLICKS.getCode());
        param.setBidAmount(1);

        Map<String, String> equipment = new HashMap<>();
        equipment.put("adCampaignGroupId", adCampaignGroupId + "");
        param.setEquipment(equipment);
        return param;
    }

    private String getFBVisitPath(String visitPath) {
        if (StringUtils.isNoneBlank(NFS_CONFIG_FB_VISIT_DOMAIN)) {
            return visitPath.replaceAll(NFS_CONFIG_DOMAIN, NFS_CONFIG_FB_VISIT_DOMAIN);
        } else {
            return visitPath;
        }
    }
}
